# encoding: utf-8

import pandas as pd
import akshare as ak

from datetime import date, timedelta
from core.common import retry_except


class AkShare:

    @staticmethod
    @retry_except
    def get_stock_index(symbol, period, start_date, end_date):
        """
        东方财富网-中国股票指数-行情数据
        http://quote.eastmoney.com/center/hszs.html
        :param symbol:	str	symbol="399282"; 指数代码，此处不用市场标识
        :param period:	str	period="daily"; choice of {'daily', 'weekly', 'monthly'}
        :param start_date:	str	start_date="19700101"; 开始日期
        :param end_date: str 结束时间
        :return:
        """
        index_zh_a_hist_df = ak.index_zh_a_hist(symbol=symbol, period=period, start_date=start_date, end_date=end_date)
        return index_zh_a_hist_df

    @staticmethod
    @retry_except
    def get_open_fund(symbol, indicator, period):
        """
        东方财富网-天天基金网-基金数据-具体基金信息
        http://fund.eastmoney.com/pingzhongdata/710001.js
        :param symbol:	str	710001"; 需要基金代码, 可以通过调用 ak.fund_open_fund_daily_em() 获取
        :param indicator: str {"单位净值走势", "累计净值走势"}
        :param period:	{"1月", "3月", "6月", "1年", "3年", "5年", "今年来", "成立来"}
        :return:
        """
        fund_open_fund_info_em = ak.fund_open_fund_info_em(symbol=symbol, indicator=indicator, period=period)
        return fund_open_fund_info_em

    @staticmethod
    @retry_except
    def get_etf(symbol, period, start_date, end_date, adjust):
        """
        目标地址: http://quote.eastmoney.com/sz159707.html
        :param symbol:	str	symbol='159707'; ETF 代码可以在 ak.fund_etf_spot_em() 中获取或查看东财主页
        :param period:	str	period='daily'; choice of {'daily', 'weekly', 'monthly'}
        :param start_date:	str	start_date='20000101'; 开始查询的日期
        :param end_date:	str	end_date='20230104'; 结束查询的日期
        :param adjust:	str	默认返回不复权的数据; qfq: 返回前复权后的数据; hfq: 返回后复权后的数据
        :return:
        """
        fund_etf_hist_em_df = ak.fund_etf_hist_em(symbol=symbol, period=period, start_date=start_date,
                                                  end_date=end_date, adjust=adjust)
        fund_etf_hist_em_df['日期'] = pd.to_datetime(fund_etf_hist_em_df['日期'])
        return fund_etf_hist_em_df

    def crawl_stock_index(self, symbol, crawl_type):
        """
        爬取股票指数
        :param symbol:	str	symbol="399282"; 指数代码，此处不用市场标识
        :param crawl_type:	{"first", "no_first"}
        :return:
        """
        period = 'weekly'
        if crawl_type == 'first':
            start_date = '19700101'
        else:
            start_date = (date.today() - timedelta(days=35)).strftime('%Y%m%d')
        end_date = date.today().strftime('%Y%m%d')
        pd_data = self.get_stock_index(symbol, period, start_date, end_date)
        return pd_data

    def crawl_active_bond(self, symbol, crawl_type):
        """
        爬取积极债
        :param symbol:	str	symbol="399282"; 指数代码，此处不用市场标识
        :param crawl_type:	{"first", "no_first"}
        :return:
        """
        if crawl_type == 'first':
            period = '成立来'
        else:
            period = '1月'
        indicator = "单位净值走势"
        fund_open_fund_info_em_unit = self.get_open_fund(symbol=symbol, indicator=indicator, period=period)
        indicator = "累计净值走势"
        fund_open_fund_info_em_cumulative = self.get_open_fund(symbol=symbol, indicator=indicator, period=period)
        return pd.concat([fund_open_fund_info_em_unit, fund_open_fund_info_em_cumulative[['累计净值']]], axis=1)

    def crawl_pure_bond(self, symbol, crawl_type):
        """
        爬取纯债
        :param symbol:	str	symbol="399282"; 指数代码，此处不用市场标识
        :param crawl_type:	{"first", "no_first"}
        :return:
        """
        if crawl_type == 'first':
            period = '成立来'
        else:
            period = '1月'
        indicator = "单位净值走势"
        fund_open_fund_info_em_unit = self.get_open_fund(symbol=symbol, indicator=indicator, period=period)
        indicator = "累计净值走势"
        fund_open_fund_info_em_cumulative = self.get_open_fund(symbol=symbol, indicator=indicator, period=period)
        return pd.concat([fund_open_fund_info_em_unit, fund_open_fund_info_em_cumulative[['累计净值']]], axis=1)

    def crawl_stock(self, symbol, crawl_type):
        """
        爬取股票
        :param symbol:	str	symbol="399282"; 指数代码，此处不用市场标识
        :param crawl_type:	{"first", "no_first"}
        :return:
        """
        if crawl_type == 'first':
            period = '成立来'
        else:
            period = '1月'
        indicator = "单位净值走势"
        fund_open_fund_info_em_unit = self.get_open_fund(symbol=symbol, indicator=indicator, period=period)
        indicator = "累计净值走势"
        fund_open_fund_info_em_cumulative = self.get_open_fund(symbol=symbol, indicator=indicator, period=period)
        return pd.concat([fund_open_fund_info_em_unit, fund_open_fund_info_em_cumulative[['累计净值']]], axis=1)

    def crawl_etf(self, symbol, crawl_type):
        """
        爬取ETF行情
        :param symbol:	str	symbol="399282"; 指数代码，此处不用市场标识
        :param crawl_type:	{"first", "no_first"}
        :return:
        """
        period = 'weekly'
        if crawl_type == 'first':
            start_date = '19700101'
        else:
            start_date = (date.today() - timedelta(days=35)).strftime('%Y%m%d')
        end_date = date.today().strftime('%Y%m%d')
        adjust = ''
        fund_etf_hist_em_no = self.get_etf(symbol, period, start_date, end_date, adjust)
        adjust = 'hfq'
        fund_etf_hist_em_hfq = self.get_etf(symbol, period, start_date, end_date, adjust)
        return pd.concat([
            fund_etf_hist_em_no,
            fund_etf_hist_em_no[['日期', '收盘']].rename(columns={'日期': '净值日期', '收盘': '单位净值'}),
            fund_etf_hist_em_hfq[['收盘']].rename(columns={'收盘': '累计净值'})
        ], axis=1)
